I'm trying to implement subtitles to videoview. I've used this example project :
package com.example.media.timedtexttest;
import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Locale;
import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnTimedTextListener;
import android.media.MediaPlayer.TrackInfo;
import android.media.TimedText;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends Activity implements OnTimedTextListener {
private static final String TAG = "TimedTextTest";
private TextView txtDisplay;
private static Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtDisplay = (TextView) findViewById(R.id.txtDisplay);
MediaPlayer player = MediaPlayer.create(this, R.raw.video);
try {
player.addTimedTextSource(getSubtitleFile(R.raw.sub),
MediaPlayer.MEDIA_MIMETYPE_TEXT_SUBRIP);
int textTrackIndex = findTrackIndexFor(
TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT, player.getTrackInfo());
if (textTrackIndex >= 0) {
player.selectTrack(textTrackIndex);
} else {
Log.w(TAG, "Cannot find text track!");
}
player.setOnTimedTextListener(this);
player.start();
} catch (Exception e) {
e.printStackTrace();
}
}
private int findTrackIndexFor(int mediaTrackType, TrackInfo[] trackInfo) {
int index = -1;
for (int i = 0; i < trackInfo.length; i++) {
if (trackInfo[i].getTrackType() == mediaTrackType) {
return i;
}
}
return index;
}
private String getSubtitleFile(int resId) {
String fileName = getResources().getResourceEntryName(resId);
File subtitleFile = getFileStreamPath(fileName);
if (subtitleFile.exists()) {
Log.d(TAG, "Subtitle already exists");
return subtitleFile.getAbsolutePath();
}
Log.d(TAG, "Subtitle does not exists, copy it from res/raw");
// Copy the file from the res/raw folder to your app folder on the
// device
InputStream inputStream = null;
OutputStream outputStream = null;
try {
inputStream = getResources().openRawResource(resId);
outputStream = new FileOutputStream(subtitleFile, false);
copyFile(inputStream, outputStream);
return subtitleFile.getAbsolutePath();
} catch (Exception e) {
e.printStackTrace();
} finally {
closeStreams(inputStream, outputStream);
}
return "";
}
private void copyFile(InputStream inputStream, OutputStream outputStream)
throws IOException {
final int BUFFER_SIZE = 1024;
byte[] buffer = new byte[BUFFER_SIZE];
int length = -1;
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
}
// A handy method I use to close all the streams
private void closeStreams(Closeable... closeables) {
if (closeables != null) {
for (Closeable stream : closeables) {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
#Override
public void onTimedText(final MediaPlayer mp, final TimedText text) {
if (text != null) {
handler.post(new Runnable() {
#Override
public void run() {
int seconds = mp.getCurrentPosition() / 1000;
txtDisplay.setText("[" + secondsToDuration(seconds) + "] "
+ text.getText());
}
});
}
}
// To display the seconds in the duration format 00:00:00
public String secondsToDuration(int seconds) {
return String.format("%02d:%02d:%02d", seconds / 3600,
(seconds % 3600) / 60, (seconds % 60), Locale.US);
}
}
and created exactly the same implementation and it somehow works, but if i stop video and continue subtitle doesn't continue or if i seek video to some time subtitle doesn't continue too.
What i have tried:
Every time before player.start() i set player.selectTrack(textTrackIndex);
I've tried to reregister listener when i'm doing player.start(); player.setOnTimedTextListener(this);
Please help i've spent 4 days on subtitle features... If you have some project example or snippet it would be nice :)
we have the same problem and we must implements OnSeekCompleteListener even if you nothing to do into override method
it's our code:
#Override
public void onSeekComplete(MediaPlayer mediaPlayer) {
}
and it work !!!
I hope that help you
Related
I have an arduino car which I wish to control via Bluetooth from my android phone. I've made an application for this, but when i try to send multiple consecutive messages through my OutputStream.write function, they get sent as a single, concatinated message. For example: if I call connectedThread.write("200-100"); and then connectedThread.write("300-150"), on my serial monitor it shows up as a single message: "200-100300-150". I have seen this same problem in other StackOverflow posts ( OutputStream.write() never ends , Android outputStream.write send multiple messages ), but they don't have an answer that works for me, I tried using connectedThread.flush() and it doesn't help. Here is my code (the connecting part is in another Activity, and it works fine):
package com.clickau.cosmin.bluetootharduinocarcontroller;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.SeekBar;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Controls extends AppCompatActivity {
private SeekBar speed;
private SeekBar direction;
private BluetoothSocket btSocket = DataHolder.getData();
private ConnectedThread connectedThread;
private int speedValue;
private int directionValue;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_controls);
speed = (SeekBar) findViewById(R.id.speed);
direction = (SeekBar) findViewById(R.id.direction);
speedValue = speed.getProgress();
directionValue = direction.getProgress();
speed.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progressValue, boolean fromUser)
{
speedValue = speed.getProgress()/5;
speedValue*=5;
directionValue = direction.getProgress()/5;
directionValue*=5;
/*StringBuilder str = new StringBuilder();
if (speedValue == 255)
str.append("STOP");
else
{
if (speedValue > 255)
{
str.append(speedValue - 255);
str.append('F');
}
else if (speedValue < 255)
{
str.append(255-speedValue);
str.append('S');
}
if (directionValue > 100)
{
str.append('D');
str.append(directionValue-100);
}
else if (directionValue < 100)
{
str.append('S');
str.append(100 - directionValue);
}
}
str.append('\n');
connectedThread.write(str.toString());*/
connectedThread.write(speedValue+ "+" + directionValue);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar)
{
}
#Override
public void onStopTrackingTouch(SeekBar seekBar)
{
speed.setProgress(255);
speedValue = speed.getProgress();
}
});
direction.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progressValue, boolean fromUser)
{
speedValue = speed.getProgress()/5;
speedValue*=5;
directionValue = direction.getProgress()/5;
directionValue*=5;
/*StringBuilder str = new StringBuilder();
if (speedValue == 255)
str.append("STOP");
else
{
if (speedValue > 255)
{
str.append(speedValue - 255);
str.append('F');
}
else if (speedValue < 255)
{
str.append(255-speedValue);
str.append('S');
}
if (directionValue > 100)
{
str.append('D');
str.append(directionValue-100);
}
else if (directionValue < 100)
{
str.append('S');
str.append(100 - directionValue);
}
}
str.append('\n');
connectedThread.write(str.toString());*/
connectedThread.write(speedValue+ "+" + directionValue);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar)
{
}
#Override
public void onStopTrackingTouch(SeekBar seekBar)
{
direction.setProgress(100);
directionValue = direction.getProgress();
}
});
connectedThread = new ConnectedThread(btSocket);
connectedThread.start();
}
private class ConnectedThread extends Thread
{
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket)
{
InputStream tmpIn = null;
OutputStream tmpOut = null;
try{
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
}catch(IOException e) {
Log.e("ERROR", "Connected Thread");
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
/*public void run()
{
byte[] buffer = new byte[256];
int bytes;
while (true)
{
try{
bytes = mmInStream.read(buffer);
String readMessage = new String(buffer, 0, bytes);
bluetoothIn.obtainMessage(handlerState, bytes, -1 ,readMessage).sendToTarget();
} catch (IOException e)
{
break;
}
}
}*/
public void write(String input)
{
byte[] msgBuffer = input.getBytes();
try{
mmOutStream.write(msgBuffer);
mmOutStream.flush();
}catch(IOException e)
{
Toast.makeText(getBaseContext(), "Connection Failure", Toast.LENGTH_LONG).show();
finish();
}
}
}
}
I think this might be an optimization for bluetooth, but it's really annoying because I need those messages to be sent sepparatly when I move the controls, not 10 seconds afterwards. Anyone know how to solve this?
I want to record the android click event when I use other apps. For each click, I record its timestamp. So, this app should run background. I use the "getevent" to catch the click event. I am not very familiar with Android operation. My code
has a bug. Its output is not very good, there are many "null"s in the output, and the record is not exactly right.(My app needs root permission)
1.MainActivity.java
package kingofne.seu.edu.ndktest;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private EditText editText = null;
private TextView textView = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.editText);
textView = (TextView) findViewById(R.id.textView);
Button btn_start = (Button) findViewById(R.id.btn_start);
if (btn_start != null) {
btn_start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(getApplicationContext(), MyService.class);
int param = 1;
if (editText != null) {
param = Integer.valueOf(String.valueOf(editText.getText()));
}
intent.putExtra("param", param);
startService(intent);
Toast.makeText(getApplicationContext(), "start", Toast.LENGTH_SHORT).show();
textView.setText(String.valueOf(System.currentTimeMillis()));
}
});
}
Button btn_stop = (Button) findViewById(R.id.btn_stop);
if (btn_stop != null) {
btn_stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(getApplicationContext(), MyService.class);
stopService(intent);
Toast.makeText(getApplicationContext(), "stop", Toast.LENGTH_SHORT).show();
}
});
}
}
}
2.MyService.java
package kingofne.seu.edu.ndktest;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MyService extends Service {
private boolean isRunning = false;
private int param = 1;
private Thread captureThread = null;
private volatile boolean doCapture = false;
public MyService() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (isRunning) {
return START_NOT_STICKY;
}
param = intent.getIntExtra("param", 1);
this.captureThread = new Thread(new Producer());
captureThread.setDaemon(true);
this.doCapture = true;
captureThread.start();
isRunning = true;
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
// stop the thread
this.doCapture = false;
// destroy the thread
this.captureThread = null;
}
private class Producer implements Runnable {
public void run() {
Log.d("ps", "going to run");
Date now = new Date();
SimpleDateFormat sDateFormat = new SimpleDateFormat(
"yyyy-MM-dd-HH-mm-ss");
String str2 = sDateFormat.format(now);
// String location = str2;
//String cmdLine = "getevent -t -l /dev/input/event" + String.valueOf(param) + " > /sdcard/guo" + ".txt";
String cmdLine = "cat /dev/input/event" + String.valueOf(param) + " > /sdcard/guo.txt";
CMDExecute cmd = new CMDExecute();
try {
// cmd.run_su("getevent -t > /sdcard/Yang_"+location+".txt");
cmd.run_su(cmdLine);
} catch (IOException e) {
// TODO Auto-generated catch block
Log.d("ps", "error");
e.printStackTrace();
}
}
};
class CMDExecute {
public synchronized String run(String[] cmd, String workdirectory)
throws IOException {
String result = "";
try {
ProcessBuilder builder = new ProcessBuilder(cmd);
BufferedReader in = null;
// 设置一个路径
if (workdirectory != null) {
builder.directory(new File(workdirectory));
builder.redirectErrorStream(true);
Process process = builder.start();
process.waitFor();
in = new BufferedReader(new InputStreamReader(process
.getInputStream()));
char[] re = new char[1024];
int readNum;
while ((readNum = in.read(re, 0, 1024)) != -1) {
// re[readNum] = '\0';
result = result + new String(re, 0, readNum);
}
}
if (in != null) {
in.close();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return result;
}
public synchronized String run_su(String cmd)
throws IOException {
String result = "";
Process p=null;
try {
p = Runtime.getRuntime().exec("su");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
DataOutputStream os = new DataOutputStream(p.getOutputStream());
BufferedReader is = new BufferedReader(new InputStreamReader(p.getInputStream()));
try {
String istmp;
os.writeBytes(cmd+"\n");
//os.writeBytes("exit\n");
os.flush();
os.writeBytes("exit\n");
os.flush();
p.waitFor();
is.close();
os.close();
p.destroy();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} return result;
}
}
}
I am developing an app to uploading ,displaying and downloading files from G Drive. Unfortunately When downloading I am getting
com.google.api.client.http.HttpResponseException: 401 Unauthorized.
Please help me to solve this problem.
Here I am assigning
credential = GoogleAccountCredential.usingOAuth2(this,DriveScopes.DRIVE);
service=new Drive.Builder(AndroidHttp.newCompatibleTransport(),new GsonFactory(),credential).build();
My Code Is:
package com.example.googledrive;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import com.google.api.client.http.FileContent;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.Drive.Children;
import com.google.api.services.drive.Drive.Files;
import com.google.api.services.drive.Drive.Files.Get;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.ChildList;
import com.google.api.services.drive.model.ChildReference;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.StrictMode;
import android.provider.MediaStore;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
public class MainActivity extends Activity {
static final int REQUEST_ACCOUNT_PICKER = 1;
static final int REQUEST_AUTHORIZATION = 2;
static final int CAPTURE_IMAGE = 3;
private static Uri fileUri;
private static Drive service;
private ProgressDialog progressDialog;
private GoogleAccountCredential credential;
String fileId;
String fileName;
String downloadUrl;
ListView listView;
Activity activity;
String sdCardPadth;
List<File> allFileList;
ArrayList<String> fileType;
ArrayList<String> mainTitleList;
ArrayList<String> fileIdList;
ArrayList<String> alternateUrlList;
ArrayList<Integer> fileSizeList;
FileTitlesAdapter myAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.uploadedFilesList);
allFileList = new ArrayList<File>();
mainTitleList = new ArrayList<String>();
alternateUrlList = new ArrayList<String>();
fileSizeList = new ArrayList<Integer>();
fileType = new ArrayList<String>();
fileIdList=new ArrayList<String>();
progressDialog=new ProgressDialog(getApplicationContext());
progressDialog.setTitle("Please Wait....");
progressDialog.setCancelable(false);
activity = this;
credential = GoogleAccountCredential.usingOAuth2(this,DriveScopes.DRIVE);
startActivityForResult(credential.newChooseAccountIntent(),REQUEST_ACCOUNT_PICKER);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View view, final int arg2,long arg3) {
// String str=itemArray.get(arg2).toString().trim();
System.out.println("mainTitleList size==="+mainTitleList.size());
System.out.println("arg2==="+arg2);
fileName = (String)mainTitleList.get(arg2);
mainTitleList.clear();
//fileSizeList.clear();
final String fileTypeStr=fileType.get(arg2);
fileType.clear();
if(fileTypeStr.contains("application/vnd.google-apps.folder"))
{
Thread t = new Thread(new Runnable() {
#Override
public void run() {
boolean b=true;
try {
String dirUrl=alternateUrlList.get(arg2);
alternateUrlList.clear();
System.out.println("Folder Name Is:"+fileName);
System.out.println("Folder Type Is:"+fileTypeStr);
System.out.println("Folder URL Is:"+dirUrl);
String fileId=fileIdList.get(arg2);
System.out.println("Folder Id Is:"+fileId);
//retrieveAllFilesFromDir(service, fileId, b);
//retrieveAllFiles1(service, b, fileId);
//Files.List request = service.children().get(fileId, null);
Files.List request = service.files().list().setQ("'" + fileId + "' in parents ");
retrieveAllFiles(service,request,b);
//retrieveAllFiles(service, b);
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("Exception In retrieveAllFiles Dir Is:"+e);
e.printStackTrace();
}
}
});t.start();
}
else
{
try {
System.out.println("fileSizeList size===="+fileSizeList.size());
System.out.println("arg2===="+arg2);
Integer fileSize = (int) fileSizeList.get(arg2);
downloadUrl = alternateUrlList.get(arg2);
byte[] size = new byte[fileSize];
int byteRead = 0, byteWritten = 0;
sdCardPadth = Environment.getExternalStorageDirectory().getPath();
System.out.println("Download Url==="+downloadUrl);
new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
InputStream inStream=downloadFile(service, downloadUrl);
java.io.File inFile=new java.io.File(sdCardPadth+"/"+fileName+"1");
System.out.println("File Succesfully Stored");
}
}).start();
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("Exception In get Integer Is:" + e);
e.printStackTrace();
}
}
}
});
}
#Override
protected void onActivityResult(final int requestCode,
final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_ACCOUNT_PICKER:
if (resultCode == RESULT_OK && data != null
&& data.getExtras() != null) {
String accountName = data
.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
credential.setSelectedAccountName(accountName);
service = getDriveService(credential);
final boolean b=false;
Thread t=new Thread(new Runnable() {
#Override
public void run() {
try
{
Files.List request = service.files().list().setQ("hidden="+b);
retrieveAllFiles(service,request,b);
} catch (Exception e) {
System.out.println("Exception Is:"+e);
e.printStackTrace();
}
}
}) ;t.start();
}
}
break;
case REQUEST_AUTHORIZATION:
if (resultCode == Activity.RESULT_OK) {
System.out.println("REQUEST_AUTHORIZATION case Is:"
+ REQUEST_AUTHORIZATION);
saveFileToDrive();
} else {
startActivityForResult(credential.newChooseAccountIntent(),
REQUEST_ACCOUNT_PICKER);
}
break;
case CAPTURE_IMAGE:
if (resultCode == Activity.RESULT_OK) {
System.out.println("CAPTURE_IMAGE case Is:" + CAPTURE_IMAGE);
saveFileToDrive();
}
}
}
private void saveFileToDrive() {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
// File's binary content
System.out.println("run method");
java.io.File fileContent = new java.io.File(fileUri.getPath());
FileContent mediaContent = new FileContent("image/jpeg",fileContent);
// File's metadata.
File body = new File();
body.setTitle(fileContent.getName());
body.setMimeType("image/jpeg");
File file=null;
try {
file = service.files().insert(body, mediaContent).execute();
} catch (Exception e) {
System.out.println("Exception In Insert File Is"+e);
e.printStackTrace();
}
if (file != null) {
showToast("Photo uploaded: " + file.getTitle());
System.out.println("photo sucessfullly uploaded:"+ fileId);boolean b=false;
Files.List request = service.files().list().setQ("hidden="+b);
retrieveAllFiles(service,request,b);
}
} catch (UserRecoverableAuthIOException e) {
startActivityForResult(e.getIntent(), REQUEST_AUTHORIZATION);
} catch (IOException e) {
e.printStackTrace();
}
}
});
t.start();
}
private Drive getDriveService(GoogleAccountCredential credential) {
return new Drive.Builder(AndroidHttp.newCompatibleTransport(),
new GsonFactory(), credential).build();
}
public void showToast(final String toast) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), toast,Toast.LENGTH_SHORT).show();
}
});
}
private List<File> retrieveAllFiles(Drive service,Files.List request,boolean b) throws IOException {
List<File> result = new ArrayList<File>();
final ArrayList<String> titleList = new ArrayList<String>();
String fileUrl = "";
do {
try {
FileList files = request.execute();
result.addAll(files.getItems());
request.setPageToken(files.getNextPageToken());
for (int i = 0; i < result.size(); i++) {
File tempFile = result.get(i);
String fileTypeStr = tempFile.getMimeType();
String fileName = tempFile.getTitle();
titleList.add(fileName);
fileId = tempFile.getId();
fileIdList.add(fileId);
fileUrl = tempFile.getAlternateLink();
System.out.println("<><>< fileUrl Is:" + fileUrl);
alternateUrlList.add(fileUrl);
fileType.add(fileTypeStr);
mainTitleList.add(fileName);
try {
Integer fileSize =tempFile.getFileSize()==null?100:(int) (long) tempFile.getFileSize();
fileSizeList.add(fileSize);
System.out.println("<><>< fileSize Is:" + fileSize);
} catch (Exception e) {
fileSizeList.add(2000);
e.printStackTrace();
}
}
try {
runOnUiThread(new Runnable() {
public void run() {
myAdapter = new FileTitlesAdapter(activity,
fileType, mainTitleList, alternateUrlList,
fileSizeList);
listView.setAdapter(myAdapter);
}
});
} catch (Exception e) {
System.out.println("Exception Setting ListView Is:" + e);
e.printStackTrace();
}
} catch (IOException e) {
System.out.println("An error occurred in retrieveAllFiles:"+ e);
request.setPageToken(null);
}
} while (request.getPageToken() != null
&& request.getPageToken().length() > 0);
return result;
}
private static InputStream downloadFile(Drive service, String url) {
System.out.println("downloadFile is called service=="+service);
if (url != null && url.length() > 0) {
try {
System.out.println("downloadFile is called try");
HttpResponse resp =service.getRequestFactory().buildGetRequest(new GenericUrl(url)).execute();
System.out.println("resp.getContent()===="+resp.getContent());
return resp.getContent();
} catch (Exception e) {
System.out.println("Exception Is:"+e);
e.printStackTrace();
return null;
}
} else {
System.out.println("No Exception No Output");
return null;
}
}
}
This is code that I use to download File from google Drive
new AsyncTask<Void, Integer, Boolean>() {
#Override
protected Boolean doInBackground(Void... params) {
try {
File file = service.files().get("path in drive").execute();
java.io.File toFile = new java.io.File("where you want to store");
toFile.createNewFile();
HttpDownloadManager downloader = new HttpDownloadManager(file, toFile);
downloader.setListener(new HttpDownloadManager.FileDownloadProgressListener() {
public void downloadProgress(long bytesRead, long totalBytes) {
Log.i("chauster",totalBytes);
Log.i("chauster",bytesRead);
}
#Override
public void downloadFinished() {
// TODO Auto-generated method stub
}
#Override
public void downloadFailedWithError(Exception e) {
// TODO Auto-generated method stub
}
});
return downloader.download(service);
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean result) {
};
}.execute();
HttpDownloadManager.java
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpResponse;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.model.File;
import com.grandex.ShareInfomation.ShareData;
import com.grandex.ShareInfomation.ShareData.ToolTapState;
public class HttpDownloadManager {
private String donwloadUrl;
private String toFile;
private FileDownloadProgressListener listener;
private long totalBytes;
public void setListener(FileDownloadProgressListener listener) {
this.listener = listener;
}
public HttpDownloadManager(File sourceFile, java.io.File destinationFile) {
super();
this.donwloadUrl = sourceFile.getDownloadUrl();
this.toFile = destinationFile.toString();
this.totalBytes = sourceFile.getFileSize();
}
public static interface FileDownloadProgressListener {
public void downloadProgress(long bytesRead, long totalBytes);
public void downloadFinished();
public void downloadFailedWithError(Exception e);
}
public boolean download(Drive service) {
HttpResponse respEntity = null;
try {
// URL url = new URL(urlString);
respEntity = service.getRequestFactory()
.buildGetRequest(new GenericUrl(donwloadUrl)).execute();
InputStream in = respEntity.getContent();
if(totalBytes == 0) {
totalBytes = respEntity.getContentLoggingLimit();
}
try {
FileOutputStream f = new FileOutputStream(toFile) {
#Override
public void write(byte[] buffer, int byteOffset,
int byteCount) throws IOException {
// TODO Auto-generated method stub
super.write(buffer, byteOffset, byteCount);
}
}
};
byte[] buffer = new byte[1024];
int len1 = 0;
long bytesRead = 0;
while ((len1 = in.read(buffer)) > 0) {
f.write(buffer, 0, len1);
if (listener != null) {
bytesRead += len1;
listener.downloadProgress(bytesRead, totalBytes);
}
}
f.close();
} catch (Exception e) {
if (listener != null) {
listener.downloadFailedWithError(e);
}
return false;
}
if (listener != null) {
listener.downloadFinished();
}
return true;
} catch (IOException ex) {
if (listener != null) {
listener.downloadFailedWithError(ex);
return false;
}
} finally {
if(respEntity != null) {
try {
respEntity.disconnect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return false;
}
}
Nowhere in your code are you setting the Authorization header.
You need something like
setRequestProperty("Authorization", "OAuth " + "***ACCESS_TOKEN***");
For any 401/403 errors it's well worth getting your request working on the Oauth. Try this out
Please check below code for download apk file from google drive
implementation 'com.google.android.material:material:1.0.0'
Add uses permission
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
Create a file provider
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external"
path="." />
<external-files-path
name="external_files"
path="." />
<files-path
name="files"
path="." />
Now declare the file provider inside the manifest
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_provider_paths" />
Add some value inside strings.xml file
<resources>
<string name="app_name">Download APK</string>
<string name="downloading">Downloading...</string>
<string name="title_file_download">APK is downloading</string>
<string name="storage_access_required">Storage access is required to downloading the file.</string>
<string name="storage_permission_denied">Storage permission request was denied.</string>
<string name="ok">OK</string>
Create a download controller
package com.hktpayment.mytmoney.pos.mauritius.util
import android.app.Dialog
import android.app.DownloadManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.util.Log
import android.widget.ProgressBar
import android.widget.Toast
import androidx.core.content.FileProvider
import com.hktpayment.mytmoney.pos.mauritius.BuildConfig
import com.hktpayment.mytmoney.pos.mauritius.R
import java.io.File
class DownloadController(
private val context: Context,
private val url: String,
private val progressBar: Dialog
) {
companion object {
private const val FILE_NAME = "SampleDownloadApp.apk"
private const val FILE_BASE_PATH = "file://"
private const val MIME_TYPE = "application/vnd.android.package-archive"
private const val PROVIDER_PATH = ".provider"
private const val APP_INSTALL_PATH = "application/vnd.android.package-
archive"
}
private lateinit var downloadManager: DownloadManager
fun enqueueDownload() {
var destination =
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString()
+ "/"
destination += FILE_NAME
val uri = Uri.parse("$FILE_BASE_PATH$destination")
val file = File(destination)
if (file.exists()) file.delete()
downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as
DownloadManager
val downloadUri = Uri.parse(url)
val request = DownloadManager.Request(downloadUri)
request.setMimeType(MIME_TYPE)
request.setTitle(context.getString(R.string.title_file_download))
request.setDescription(context.getString(R.string.downloading))
// set destination
request.setDestinationUri(uri)
showInstallOption(destination, uri)
// Enqueue a new download and same the referenceId
downloadManager.enqueue(request)
Toast.makeText(context, context.getString(R.string.downloading),
Toast.LENGTH_LONG)
.show()
}
private fun showInstallOption(
destination: String,
uri: Uri
) {
// set BroadcastReceiver to install app when .apk is downloaded
progressBar.show()
val onComplete = object : BroadcastReceiver() {
override fun onReceive(
context: Context,
intent: Intent
) {
progressBar.dismiss()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val contentUri = FileProvider.getUriForFile(
context,
BuildConfig.APPLICATION_ID + PROVIDER_PATH,
File(destination)
)
val install = Intent(Intent.ACTION_VIEW)
install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
install.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
install.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
install.data = contentUri
context.startActivity(install)
context.unregisterReceiver(this)
// finish()
} else {
val install = Intent(Intent.ACTION_VIEW)
install.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
install.setDataAndType(
uri,
APP_INSTALL_PATH
)
context.startActivity(install)
context.unregisterReceiver(this)
// finish()
}
}
}
context.registerReceiver(onComplete, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
}
}
In this activity, we are checking storage permission first. If permission is granted than calling download function otherwise requesting for storage permission.
val apkUrl = "https://download .apk"
downloadController = DownloadController(this, apkUrl)
downloadController.enqueueDownload()
I am trying to develop a application. It is a radio application. When i use a method to show meta data that time it is creating some problem.
1.Play Pause button are not working smoothly.
2.Taking more time to show layout.
here is the main activity code:
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.widget.ImageButton;
import android.widget.TextView;
public class IRadioActivity extends Activity implements
MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener,
MediaPlayer.OnErrorListener, MediaPlayer.OnBufferingUpdateListener {
private String TAG = getClass().getSimpleName();
private MediaPlayer mp = null;
private ImageButton btnPlay;
String title;
String artist;
private static Context con;
Timer timer;
TextView StationName;
String Stationurl = "http://95.211.82.139:8048";
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
IRadioActivity.con = this;
btnPlay = (ImageButton) findViewById(R.id.btnPlay);
mp = new MediaPlayer();
mp.setOnCompletionListener(this); // Important
btnPlay.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
// check for already playing
if (mp.isPlaying()) {
if (mp != null) {
mp.pause();
// Changing button image to play button
btnPlay.setImageResource(R.drawable.btn_play);
}
} else {
// Resume song
if (mp != null) {
mp.start();
// Changing button image to pause button
btnPlay.setImageResource(R.drawable.btn_pause);
}
}
}
});
playSong();
getMeta();
}
public void playSong() {
// Play song
try {
mp.reset();
mp.setDataSource(Stationurl);
mp.prepare();
mp.start();
// Displaying Song title
// Changing Button Image to pause image
btnPlay.setImageResource(R.drawable.btn_pause);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void onDestroy() {
super.onDestroy();
mp.release();
}
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
}
// ----------------
public boolean onError(MediaPlayer mp, int what, int extra) {
StringBuilder sb = new StringBuilder();
sb.append("Media Player Error: ");
switch (what) {
case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
sb.append("Not Valid for Progressive Playback");
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
sb.append("Server Died");
break;
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
sb.append("Unknown");
break;
default:
sb.append(" Non standard (");
sb.append(what);
sb.append(")");
}
sb.append(" (" + what + ") ");
sb.append(extra);
Log.e(TAG, sb.toString());
return true;
}
public void onBufferingUpdate(MediaPlayer mp, int percent) {
Log.d(TAG, "PlayerService onBufferingUpdate : " + percent + "%");
}
// .....top bar button....//
public void getMeta() {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
URL url;
// Message msg = handler.obtainMessage();
try {
// url = new URL("http://relay5.slayradio.org:8000");
url = new URL(Stationurl);
final IcyStreamMeta icy = new IcyStreamMeta(url);
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
// Typeface book = Typeface.createFromAsset(
// getAssets(), "fonts/Neutra2Text-Book.otf");
final TextView songTitle = (TextView) findViewById(R.id.songName);
final TextView artistName = (TextView) findViewById(R.id.artistName);
try {
artistName.setText(icy.getArtist().toString()
.trim());
artistName.setText(icy.getArtist().toString()
.trim());
songTitle.setText(icy.getTitle().toString()
.trim());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, 0, 500);
}
#Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
}
}
Facing those problems when i use getMeta(); method.
Main Class for this method is:
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class IcyStreamMeta<Message> {
protected URL streamUrl;
private Map<String, String> metadata;
private boolean isError;
public IcyStreamMeta(URL streamUrl) {
setStreamUrl(streamUrl);
isError = false;
}
/**
* Get artist using stream's title
*
* #return String
* #throws IOException
*/
public String getArtist() throws IOException {
Map<String, String> data = getMetadata();
if (!data.containsKey("StreamTitle"))
return "";
String streamTitle = data.get("StreamTitle");
String title = streamTitle.substring(0, streamTitle.indexOf("-"));
return title.trim();
}
/**
* Get title using stream's title
*
* #return String
* #throws IOException
*/
public String getTitle() throws IOException {
Map<String, String> data = getMetadata();
if (!data.containsKey("StreamTitle"))
return "";
String streamTitle = data.get("StreamTitle");
String artist = streamTitle.substring(streamTitle.indexOf("-")+1);
return artist.trim();
}
public Map<String, String> getMetadata() throws IOException {
if (metadata == null) {
refreshMeta();
}
return metadata;
}
public void refreshMeta() throws IOException {
retreiveMetadata();
}
private void retreiveMetadata() throws IOException {
URLConnection con = streamUrl.openConnection();
con.setRequestProperty("Icy-MetaData", "1");
con.setRequestProperty("Connection", "close");
con.setRequestProperty("Accept", null);
con.connect();
int metaDataOffset = 0;
Map<String, List<String>> headers = con.getHeaderFields();
InputStream stream = con.getInputStream();
if (headers.containsKey("icy-metaint")) {
// Headers are sent via HTTP
metaDataOffset = Integer.parseInt(headers.get("icy-metaint").get(0));
} else {
// Headers are sent within a stream
StringBuilder strHeaders = new StringBuilder();
char c;
while ((c = (char)stream.read()) != -1) {
strHeaders.append(c);
if (strHeaders.length() > 5 && (strHeaders.substring((strHeaders.length() - 4), strHeaders.length()).equals("\r\n\r\n"))) {
// end of headers
break;
}
}
// Match headers to get metadata offset within a stream
Pattern p = Pattern.compile("\\r\\n(icy-metaint):\\s*(.*)\\r\\n");
Matcher m = p.matcher(strHeaders.toString());
if (m.find()) {
metaDataOffset = Integer.parseInt(m.group(2));
}
}
// In case no data was sent
if (metaDataOffset == 0) {
isError = true;
return;
}
// Read metadata
int b;
int count = 0;
int metaDataLength = 4080; // 4080 is the max length
boolean inData = false;
StringBuilder metaData = new StringBuilder();
// Stream position should be either at the beginning or right after headers
while ((b = stream.read()) != -1) {
count++;
// Length of the metadata
if (count == metaDataOffset + 1) {
metaDataLength = b * 16;
}
if (count > metaDataOffset + 1 && count < (metaDataOffset + metaDataLength)) {
inData = true;
} else {
inData = false;
}
if (inData) {
if (b != 0) {
metaData.append((char)b);
}
}
if (count > (metaDataOffset + metaDataLength)) {
break;
}
}
// Set the data
metadata = IcyStreamMeta.parseMetadata(metaData.toString());
// Close
stream.close();
}
public boolean isError() {
return isError;
}
public URL getStreamUrl() {
return streamUrl;
}
public void setStreamUrl(URL streamUrl) {
this.metadata = null;
this.streamUrl = streamUrl;
this.isError = false;
}
public static Map<String, String> parseMetadata(String metaString) {
Map<String, String> metadata = new HashMap();
String[] metaParts = metaString.split(";");
Pattern p = Pattern.compile("^([a-zA-Z]+)=\\'([^\\']*)\\'$");
Matcher m;
for (int i = 0; i < metaParts.length; i++) {
m = p.matcher(metaParts[i]);
if (m.find()) {
metadata.put((String)m.group(1), (String)m.group(2));
}
}
return metadata;
}
}
Use prepareAsync() and not prepare(). See the documentation here: http://developer.android.com/guide/topics/media/mediaplayer.html#preparingasync
I'm using a Freeduino (Arduino Uno compatible) with a Samsung Galaxy Tab 10.1 running ICS (4) and I have succeeded in writing from the Arduino to the Android, but I have not been able to read from the Android in the Arduino sketch.
Here's the Android class for the USB Accessory:
package com.kegui.test;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.util.ArrayList;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import com.kegui.test.Scripto;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class USBAccess extends Activity implements Runnable, OnClickListener {
private static final String ACTION_USB_PERMISSION = "com.google.android.DemoKit.action.USB_PERMISSION";
protected static final String TAG = "KegUI";
private UsbManager mUsbManager;
private PendingIntent mPermissionIntent;
private boolean mPermissionRequestPending;
private TextView debugtext = null;
private Button button1 = null;
private Button button2 = null;
private boolean button2visible = false;
UsbAccessory mAccessory;
ParcelFileDescriptor mFileDescriptor;
FileInputStream mInputStream;
FileOutputStream mOutputStream;
private static final int MESSAGE_BUTTON_PRESSED = 1;
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.i("KegApp", "***********************Received*************************");
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (intent.getBooleanExtra(
UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
openAccessory(accessory);
} else {
Log.d(TAG, "permission denied for accessory "
+ accessory);
}
mPermissionRequestPending = false;
}
} else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (accessory != null && accessory.equals(mAccessory)) {
closeAccessory();
}
}
}
};
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
setContentView(R.layout.main);
final Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
new TempUpdateTask().execute("testing");
}
});
registerReceiver(mUsbReceiver, filter);
Log.d(TAG,"on Create'd");
}
#Override
public void onResume() {
super.onResume();
if (mInputStream != null && mOutputStream != null) {
return;
}
UsbAccessory[] accessories = mUsbManager.getAccessoryList();
UsbAccessory accessory = (accessories == null ? null : accessories[0]);
if (accessory != null) {
if (mUsbManager.hasPermission(accessory)) {
openAccessory(accessory);
} else {
synchronized (mUsbReceiver) {
if (!mPermissionRequestPending) {
mUsbManager.requestPermission(accessory,
mPermissionIntent);
mPermissionRequestPending = true;
}
}
}
} else {
Log.d(TAG, "mAccessory is null");
}
}
#Override
public void onPause() {
super.onPause();
closeAccessory();
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mUsbReceiver);
}
private void openAccessory(UsbAccessory accessory) {
mFileDescriptor = mUsbManager.openAccessory(accessory);
if (mFileDescriptor != null) {
mAccessory = accessory;
FileDescriptor fd = mFileDescriptor.getFileDescriptor();
mInputStream = new FileInputStream(fd);
mOutputStream = new FileOutputStream(fd);
Thread thread = new Thread(null, this, "KegApp");
thread.start();
//enableControls(true);
} else {
Log.d(TAG, "accessory open fail");
}
}
public void run() {
int ret = 0;
byte[] buffer = new byte[16384];
int i;
Log.i("KegApp", "***********************in run*************************");
while (ret >= 0) {
try {
ret = mInputStream.read(buffer); // this will be always positive, as long as the stream is not closed
} catch (IOException e) {
break;
}
i = 0;
while (i < ret) {
Message m = Message.obtain(messageHandler, MESSAGE_BUTTON_PRESSED);
m.obj = buffer[i];
messageHandler.sendMessage(m);
i++;
}
}
}
private void closeAccessory() {
//enableControls(false);
try {
if (mFileDescriptor != null) {
mFileDescriptor.close();
}
} catch (IOException e) {
} finally {
mFileDescriptor = null;
mAccessory = null;
}
}
public void sendCommand(FileOutputStream mStream) {
BufferedOutputStream bo = new BufferedOutputStream(mStream);
// if (mStream != null && message.length > 0) {
try {
Log.i("KegApp", "***********************sending command now*************************");
bo.write(1); //message, 0, 3);
} catch (IOException e) {
Log.e(TAG, "write failed", e);
}
// }
}
#Override
public void onClick(View v) {
// Send some message to Arduino board, e.g. "13"
Log.e(TAG, "write failed");
}
// Instantiating the Handler associated with the main thread.
private Handler messageHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
Log.i("KegApp", "***********************message handler before " + msg.what + "************************");
try {
String load = msg.obj.toString();
Log.i("KegApp", "***********************in message handler*************************");
/*
if (button2visible==false) {
debugtext.setText("Received message: "+String.valueOf(load));
button2.setVisibility(View.VISIBLE);
button2visible = true;
} else {
debugtext.setText("");
button2.setVisibility(View.GONE);
button2visible = false;
}
*/
new TempUpdateTask().execute(load);
} catch (Exception e) {
Log.e(TAG, "message failed", e);
}
}
};
// UpdateData Asynchronously sends the value received from ADK Main Board.
// This is triggered by onReceive()
class TempUpdateTask extends AsyncTask<String, String, String> {
// Called to initiate the background activity
protected String doInBackground(String... sensorValue) {
try {
Log.i("KegApp", "***********************calling sendcommand*********************");
sendCommand(mOutputStream);
Log.i("KegApp", "*********************incoming-sensorValue*********************" );
ArduinoMessage arduinoMessage = new ArduinoMessage(sensorValue[0]);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String returnString = String.valueOf(sensorValue[0]);//String.valueOf(sensorValue[0]) + " F";
publishProgress(String.valueOf(sensorValue[0]));
return (returnString); // This goes to result
}
// Called when there's a status to be updated
#Override
protected void onProgressUpdate(String... values) {
// Init TextView Widget to display ADC sensor value in numeric.
TextView tvAdcvalue = (TextView) findViewById(R.id.tvTemp);
tvAdcvalue.setText(String.valueOf(values[0]));
// Not used in this case
}
// Called once the background activity has completed
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
closeAccessory();
}
}
}
Here's my Arduino Sketch:
#include <FHB.h>
#include <Max3421e.h>
#include <Max3421e_constants.h>
#include <Max_LCD.h>
#include <Usb.h>
//FREEDUINO ONLY------------------------------------
//END FREEDUINO ONLY------------------------------------
int pin_light_sensor_1=A0;
int pin_output_sensor=9;
int currLightLevel=0;
//int prevLightLevel=0;
//int lightStableRange=90;
int delayTime=3000;
int loopCtr=0;
char cSTX=char(2);
char cSOH=char(1);
char cEOT=char(4);
char cGS=char(29);
char cRS=char(30);
char cCR=char(13);
char cLF=char(10);
//FREEDUINO ONLY------------------------------------
AndroidAccessory acc("Company Inc.",
"Kegbot5K datawriter",
"Kegbot 5000 data writer",
"1.0",
"http://companyinc.com",
"0000000012345678");
//END FREEDUINO ONLY------------------------------------
void setup()
{
pinMode(pin_light_sensor_1, INPUT);
pinMode(pin_output_sensor, OUTPUT);
Serial.begin(57600);
//FREEDUINO ONLY------------------------------------
Serial.println("pre-power");
acc.powerOn();
Serial.println("post-power");
//END FREEDUINO ONLY------------------------------------
}
void loop()
{
byte msg[3];
if (acc.isConnected()) {
currLightLevel = analogRead(pin_light_sensor_1);
//sysPrint(delayTime*loopCtr);
//sysPrint(",");
//sysPrint(currLightLevel);
writeDataMessage("LGH01", currLightLevel);
}
delay(1000);
if (acc.isConnected()) {
int len = acc.read(msg, sizeof(msg), 1);
Serial.println(len);
if (len > 0){
for (int index=0; index < len; index++){
digitalWrite(pin_output_sensor, 1);
delay(500);
digitalWrite(pin_output_sensor, 0);
}
}
}
loopCtr++;
delay(delayTime);
}
void writeHeader(String msgType)
{
sysPrint(cSTX);
sysPrint(cSTX);
sysPrint(cSOH);
sysPrint(msgType);
sysPrint(cGS);
}
void writeFooter()
{
sysPrint(cEOT);
sysPrintLn(cEOT);
}
void writeDataMessage(String sensorID, int value)
{
writeHeader("DATA");
sysPrint(sensorID);
sysPrint(cRS);
sysPrint(value);
writeFooter();
}
void writeAlarmMessage(String sensorID, String message)
//Do we need to enforce the 5 char sensorID here? I don't think so...
{
writeHeader("ALRM");
sysPrint(sensorID);
sysPrint(cRS);
sysPrint(message);
writeFooter();
}
void sysPrint(String whatToWrite)
{
int len=whatToWrite.length();
char str[len];
whatToWrite.toCharArray(str, len);
acc.write((void *)str, len);
// acc.write(&whatToWrite, whatToWrite.length());
}
void sysPrint(char whatToWrite)
{
acc.write((void *)whatToWrite, 1);
// acc.write(&whatToWrite, 1);
}
void sysPrint(int whatToWrite)
{
acc.write((void *)&whatToWrite, 1);
// acc.write(&whatToWrite, 1);
}
void sysPrintLn(String whatToWrite)
{
int len=whatToWrite.length();
char str[len];
whatToWrite.toCharArray(str, len);
acc.write((void *)str, len);
acc.write((void *)&cCR, 1);
acc.write((void *)&cLF, 1);
// acc.write(&whatToWrite, whatToWrite.length());
// acc.write(&cCR, 1);
// acc.write(&cLF, 1);
}
void sysPrintLn(char whatToWrite)
{
acc.write((void *)whatToWrite, 1);
acc.write((void *)&cCR, 1);
acc.write((void *)&cLF, 1);
// acc.write(&whatToWrite, 1);
// acc.write(&cCR, 1);
// acc.write(&cLF, 1);
}
The sendCommand function in the Android is logging that it was sent. The acc.read function is printing length to Serial output as -1, as in no input. Speaking of which, the Android logs do not show errors, so I'm thinking this might be an Arduino thing.
My Manifest has an Intent filter that's registering the device, although permissions might have something to do with it.
<intent-filter>
<action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
android:resource="#xml/accessory_filter" />
</activity>
Thanks in advance for any thoughts,
Sara
I have developed an RC helicopter that can be controlled using android by sending messages from the android to the arduino located on top of the Helicopter using Bluetooth Stick, i did not use usb yet for any project but when you are sending messages to the arduino you are using serial communication weather connected threw USB or Bluetooth i suggest to simply use Serial.read and every message you send to arduino end it with some symbol '#' for example just to separate messages and get the message character by character
this is the code to read the full message ended with '#' from the Serial port:
String getMessage()
{
String msg=""; //the message starts empty
byte ch; // the character that you use to construct the Message
byte d='#';// the separating symbol
if(Serial.available())// checks if there is a new message;
{
while(Serial.available() && Serial.peek()!=d)// while the message did not finish
{
ch=Serial.read();// get the character
msg+=(char)ch;//add the character to the message
delay(1);//wait for the next character
}
ch=Serial.read();// pop the '#' from the buffer
if(ch==d) // id finished
return msg;
else
return "NA";
}
else
return "NA"; // return "NA" if no message;
}
this function checks if there any message in the buffer if not it returns "NA".
if that did not help please inform.
Figured out what's going wrong - sendCommand is executing from the asynchronous TempTask so it doesn't get passed a valid reference to the FileOutputStream. I can execute sendCommand onClick from the main thread and receive on the Arduino just fine.