youtubeExtractor for Android - android

I want to use youtubeExtractor for android app and I found library like
compile 'com.github.HaarigerHarald:android-youtubeExtractor:master-SNAPSHOT'
There is a sample code in github I copied it. After I open app, it closes at the same time. There isn't an error in phone and also Logcat. Only there is
W/System: ClassLoader referenced unknown path: /data/app/oz.videos-1/lib/arm64 on logcat. I am not sure this is a error or not. Any suggestion? Thanks in advance.
import android.app.Activity;
import android.app.DownloadManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.SparseArray;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.Toast;
import at.huber.youtubeExtractor.VideoMeta;
import at.huber.youtubeExtractor.YouTubeExtractor;
import at.huber.youtubeExtractor.YtFile;
public class MainActivity extends Activity
{
private static String youtubeLink;
private LinearLayout mainLayout;
private ProgressBar mainProgressBar;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainLayout = (LinearLayout) findViewById(R.id.main_layout);
mainProgressBar = (ProgressBar) findViewById(R.id.prgrBar);
// Check how it was started and if we can get the youtube link
if (savedInstanceState == null && Intent.ACTION_SEND.equals(getIntent().getAction())
&& getIntent().getType() != null && "text/plain".equals(getIntent().getType()))
{
String ytLink = getIntent().getStringExtra(Intent.EXTRA_TEXT);
if (ytLink != null
&& (ytLink.contains("://youtu.be/") || ytLink.contains("youtube.com/watch?v=")))
{
youtubeLink = ytLink;
// We have a valid link
getYoutubeDownloadUrl(youtubeLink);
}
else
{
Toast.makeText(this, R.string.error_no_yt_link, Toast.LENGTH_LONG).show();
finish();
}
} else if (savedInstanceState != null && youtubeLink != null) {
getYoutubeDownloadUrl(youtubeLink);
} else {
finish();
}
}
private void getYoutubeDownloadUrl(String youtubeLink)
{
new YouTubeExtractor(this)
{
#Override
public void onExtractionComplete(SparseArray<YtFile> ytFiles, VideoMeta vMeta) {
mainProgressBar.setVisibility(View.GONE);
if (ytFiles == null) {
// Something went wrong we got no urls. Always check this.
finish();
return;
}
// Iterate over itags
for (int i = 0, itag; i < ytFiles.size(); i++) {
itag = ytFiles.keyAt(i);
// ytFile represents one file with its url and meta data
YtFile ytFile = ytFiles.get(itag);
// Just add videos in a decent format => height -1 = audio
if (ytFile.getFormat().getHeight() == -1 || ytFile.getFormat().getHeight() >= 360) {
addButtonToMainLayout(vMeta.getTitle(), ytFile);
}
}
}
}.extract(youtubeLink, true, false);
}
private void addButtonToMainLayout(final String videoTitle, final YtFile ytfile)
{
// Display some buttons and let the user choose the format
String btnText = (ytfile.getFormat().getHeight() == -1) ? "Audio " +
ytfile.getFormat().getAudioBitrate() + " kbit/s" :
ytfile.getFormat().getHeight() + "p";
btnText += (ytfile.getFormat().isDashContainer()) ? " dash" : "";
Button btn = new Button(this);
btn.setText(btnText);
btn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String filename;
if (videoTitle.length() > 55) {
filename = videoTitle.substring(0, 55) + "." + ytfile.getFormat().getExt();
} else {
filename = videoTitle + "." + ytfile.getFormat().getExt();
}
filename = filename.replaceAll("\\\\|>|<|\"|\\||\\*|\\?|%|:|#|/", "");
downloadFromUrl(ytfile.getUrl(), videoTitle, filename);
finish();
}
});
mainLayout.addView(btn);
}
private void downloadFromUrl(String youtubeDlUrl, String downloadTitle, String fileName)
{
Uri uri = Uri.parse(youtubeDlUrl);
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setTitle(downloadTitle);
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);
}
}

Please try to implement the version 2.0.0 of the library:
implementation 'com.github.HaarigerHarald:android-youtubeExtractor:v2.0.0'

May be your savedInstanceState == null, and then finish() method called.
Try call getYoutubeDownloadUrl() with youtube link after mainProgressBar = (ProgressBar) findViewById(R.id.prgrBar);

Related

Phone manager/Battery optimizer app kills foreground service

-I am developing an application that records user location in a .csv file and uploads them to firebase storage and I've written a service to accomplish this. The service needs to run indefinitely until the user stops it (by unchecking a switch from the activity that launched the service). The service runs in foreground and after running for 15-20 minutes, the phone manager app gives "resource intensive app found" notification and kills the service. onDestroy() never gets called!. I return START_STICKY which is supposed to recreate the service and call onStartCommand() again but the service never gets created again!
I've seen some people write workarounds for this problem but they target specific android versions. My app targets android Pie and I haven't seen any "generic" solution to this problem yet. All solutions are either device/brand specific or API level specific. For now I'm testing the app on Huawei Y7 prime 2018 (Android O) and on my device, i got around this by manually disallowing the phone manager app to manage my application, this way the service does run indefinitely until the user kills it from the app. The nature of the application is such that i need minimum user engagement and i don't expect the users to go through the hassle of manually disabling my app from battery optimizer/phone manager app. My LocationService.java class is attached, if somebody could please provide either a better implementation of this service or some generic method to keep it alive, that'd be great. Even some hack to make sure that onDestroy() gets called before the system kills the application would work!
package com.example.bumps;
import android.Manifest;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.IBinder;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.core.content.ContextCompat;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Type;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class LocationService extends Service implements LocationListener {
private static final String CHANNEL_ID = "LocationServiceChannel";
private static final int ONGOING_NOTIFICATION_ID = 1;
public static final String PREFS_TAG = "PendingUploadPrefs";
private LocationManager locationManager;
DecimalFormat numberFormat = new DecimalFormat("#.000");
DecimalFormat coordinatesFormat = new DecimalFormat("#.00000");
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
SimpleDateFormat sdfForDir = new SimpleDateFormat("dd-MM-yyyy_hh:mm:ss");
File locationDirectory;
String currentDataDirectory;
FirebaseStorage filesStorage;
String userUUID;
List<ResumeFileUpload> pendingFileUploads;
private SharedPreferences sharedPreferences;
private SharedPreferences.Editor sharedPrefEditor;
private SOTWFormatter sotwFormatter;
#Override
public void onCreate() {
super.onCreate();
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
filesStorage = FirebaseStorage.getInstance();
pendingFileUploads = new ArrayList<>();
sharedPreferences = this.getSharedPreferences(PREFS_TAG, Context.MODE_PRIVATE);
sharedPrefEditor = sharedPreferences.edit();
sotwFormatter = new SOTWFormatter(this);
String timeStamp = sdfForDir.format(new Date());
currentDataDirectory = "RBD_" + timeStamp;
locationDirectory = new File(getExternalFilesDir(null), currentDataDirectory);
if (!locationDirectory.exists())
locationDirectory.mkdir();
}
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//userUUID = intent.getStringExtra("userUUID");
userUUID = sharedPreferences.getString("userUUID", "UNKNOWN");
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
0, 0, this);
}
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent =
PendingIntent.getActivity(this, 0, notificationIntent, 0);
createNotificationChannel();
Notification notification =
new Notification.Builder(this, CHANNEL_ID)
.setContentTitle(getText(R.string.notification_title))
.setContentText(getText(R.string.notification_message))
.setSmallIcon(R.drawable.bump)
.setContentIntent(pendingIntent)
.setTicker(getText(R.string.ticker_text))
.build();
startForeground(ONGOING_NOTIFICATION_ID, notification);
return START_STICKY;
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
"Location Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
);
NotificationManager manager = getSystemService(NotificationManager.class);
try {
manager.createNotificationChannel(serviceChannel);
} catch (Exception e) {
e.printStackTrace();
}
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
locationManager.removeUpdates(this);
}
File newFileLoc = writeLocationDataToFile(locationStringBuilder);
pendingFileUploads.add(new ResumeFileUpload(currentDataDirectory,
newFileLoc.getPath()));
uploadToStorage(newFileLoc);
/*if there are no pending files from some previous session, just save the ones
* that just got created*/
if (getPendingFileUploads() == null){
setList("PendingUploads", pendingFileUploads);
}else{
/*if there are pending uploads from some previous session, fetch them,
* update the list of pending uploads with and save for later upload*/
List<ResumeFileUpload> pUploads = getPendingFileUploads();
for (ResumeFileUpload resumeFileUpload: pendingFileUploads){
pUploads.add(resumeFileUpload);
}
setList("PendingUploads", pUploads);
}
}
private List<ResumeFileUpload> getPendingFileUploads(){
List<ResumeFileUpload> pendingUploads = null;
String serializedObject = sharedPreferences.getString("PendingUploads", null);
if (serializedObject != null){
Gson gson = new Gson();
Type type = new TypeToken<List<ResumeFileUpload>>(){}.getType();
pendingUploads = gson.fromJson(serializedObject, type);
}
return pendingUploads;
}
private boolean deleteFile(File file){
try {
Uri uri = Uri.fromFile(file);
File fdelete = new File(uri.getPath());
if (fdelete.exists()) {
if (fdelete.delete()) {
System.out.println("file Deleted :" + uri.getPath());
return true;
} else {
System.out.println("file not Deleted :" + uri.getPath());
return false;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
private File writeLocationDataToFile(StringBuilder data) {
String fileName = "Location.csv";
String colNamesLoc = "Timestamp,Latitude,Longitude,Accuracy,DirectionOfMotion,Speed\n";
File newFile = new File(locationDirectory, fileName);
try {
FileWriter fileWriter = new FileWriter(newFile);
fileWriter.append(colNamesLoc);
fileWriter.append(data.toString());
fileWriter.flush();
fileWriter.close();
Toast.makeText(this, "Saved To " + getExternalFilesDir(null)
+ "/" + fileName, Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
return newFile;
}
private void uploadToStorage(final File newFile){
Uri uri = Uri.fromFile(new File(newFile.getPath()));
StorageReference storageReference = filesStorage.getReference()
.child(userUUID + "/" + currentDataDirectory + "/" +
uri.getLastPathSegment());
UploadTask uploadTask = storageReference.putFile(uri);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Toast.makeText(LocationService.this,
newFile.getName() + " Upload Failed!", Toast.LENGTH_SHORT).show();
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
deleteFile(newFile);
Toast.makeText(LocationService.this,
newFile.getName() + " Upload Successful!", Toast.LENGTH_SHORT).show();
}
});
}
/*Location Listener*/
#Override
public void onLocationChanged(Location location) {
if (location != null) {
String lat = coordinatesFormat.format(location.getLatitude());
String lng = coordinatesFormat.format(location.getLongitude());
String bearing = "0.0";
if (location.getBearing() != 0.0)
bearing = String.valueOf(sotwFormatter.format(location.getBearing()));
int speed = (int) location.getSpeed();
String currentSpeed = String.valueOf(speed * 3.6f) + " KM/h";
String accuracy = "0.0";
if (location.getAccuracy() != 0.0)
accuracy = coordinatesFormat.format(location.getAccuracy());
String timeStamp = simpleDateFormat.format(new Date());
String locationData = timeStamp + ", " + lat +
", " + lng + ", " + accuracy + ", " + bearing + ", "
+ currentSpeed;
locationStringBuilder.append(locationData);
locationStringBuilder.append("\n");
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
/*SharedPreferences code*/
public <T> void setList(String key, List<T> list) {
Gson gson = new Gson();
String json = gson.toJson(list);
set(key, json);
}
public void set(String key, String value) {
sharedPrefEditor.putString(key, value);
sharedPrefEditor.commit();
}
}

Open gallery in specific video, without playing it

I have a camera application that can also record video. (Im developing on samsung S3)
I want to be able to open the gallery on the last recorded video.
I use this code:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(file.getAbsolutePath()), "video/3gpp");
startActivity(intent);
The problem with that code is that the video immediately starts, and when it ends
the gallery activity close.
I want to be able to open the video without playing it, exactly like in my samsung S3.
thanks in advance!
To open particular image we can use this .. and its worked .
so please check with your requirement. Hope this will helps you..
import java.io.File;
import android.app.Activity;
import android.content.Intent;
import android.media.MediaScannerConnection;
import android.media.MediaScannerConnection.MediaScannerConnectionClient;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class SDCARD123Activity extends Activity implements MediaScannerConnectionClient{
public String[] allFiles;
private String SCAN_PATH ;
private static final String FILE_TYPE="image/*";
private MediaScannerConnection conn;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
File folder = new File("/sdcard/Photo/");
allFiles = folder.list();
// uriAllFiles= new Uri[allFiles.length];
for(int i=0;i<allFiles.length;i++)
{
Log.d("all file path"+i, allFiles[i]+allFiles.length);
}
// Uri uri= Uri.fromFile(new File(Environment.getExternalStorageDirectory().toString()+"/yourfoldername/"+allFiles[0]));
SCAN_PATH=Environment.getExternalStorageDirectory().toString()+"/Photo/"+allFiles[0];
System.out.println(" SCAN_PATH " +SCAN_PATH);
Log.d("SCAN PATH", "Scan Path " + SCAN_PATH);
Button scanBtn = (Button)findViewById(R.id.scanBtn);
scanBtn.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
startScan();
}});
}
private void startScan()
{
Log.d("Connected","success"+conn);
if(conn!=null)
{
conn.disconnect();
}
conn = new MediaScannerConnection(this,this);
conn.connect();
}
#Override
public void onMediaScannerConnected() {
Log.d("onMediaScannerConnected","success"+conn);
conn.scanFile(SCAN_PATH, FILE_TYPE);
}
#Override
public void onScanCompleted(String path, Uri uri) {
try {
Log.d("onScanCompleted",uri + "success"+conn);
System.out.println("URI " + uri);
if (uri != null)
{
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
startActivity(intent);
}
} finally
{
conn.disconnect();
conn = null;
}
}
}

Finish an activity,get string typed result from a class and use that result to another activity

I'm new in android environment and started a Software development project, so my knowledge is too few in it. I need help in detail.
Problem details:
Project is on ANDROID OCR code source from github Robert m.theis
currently it's outcome is - while i take an image of any written text,it retrieves quite exact output using tesseract engine as text and search in internet.
my work is -
use the text string (digits ) and call to a phone operator.
my project name is automated mobile card recharging system.
so that i took result text from a method getText() class named OcrResult.java and put into my own activity. But i don't know why this don't working in real device.
it builds, run in emulator, but in real device at least it should show messages! But it doesn't.
i also added in manifest.xml file as (angel braces are remover here)
under activity
activity android:name="edu.sfsu.cs.orange.ocr.call.CallManager"
under application
uses-permission android:name="android.permission.CALL_PHONE"
here my code is
package edu.sfsu.cs.orange.ocr.call;
import edu.sfsu.cs.orange.ocr.OcrResult;
import edu.sfsu.cs.orange.ocr.CaptureActivity;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;
public class CallManager extends Activity
{
public static final String preString = "*111*";
public static final String postString = "#";
//to store retrieved digits
String finalString;
//to get text result from ocr result
OcrResult getStringResult = new OcrResult();
String middleString = getStringResult.getText();
//if it fails to scan desired digit,call the process again
CaptureActivity tryProcessAgain = new CaptureActivity();
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
public void setString(String x)
{
middleString = x;
}
public String getString( String toBeInserted)
{
if(toBeInserted.length() == 16)
{
int counter = 0;
char [] insertHere = new char[16];
for(int verifier = 0; verifier < 16; verifier ++)
{
insertHere[verifier] = toBeInserted.charAt(verifier);
if(!Character.isDigit(insertHere[verifier]))
{
break;
}
counter ++;
}
if(counter == 16)
{
finalString = preString + toBeInserted + postString;
return finalString;
}
else
{
// #SuppressWarnings("unused")
//Toast toast = Toast.makeText(this, " number scan invalid.....OCR failed. Please try again.", Toast.LENGTH_SHORT);
//toast.show();
return middleString;
}
}
else
{
//#SuppressWarnings("unused")
//Toast toast = Toast.makeText(this, " number scannin invalid...OCR failed. Please try again.", Toast.LENGTH_SHORT);
//toast.show();
return middleString;
}
}
public void CallToOperator(String callMe)
{
Toast toast = Toast.makeText(this,finalString,Toast.LENGTH_SHORT);
toast.show();
//Toast toast1 = Toast.makeText(this,middleString,Toast.LENGTH_SHORT);
//toast1.show();
if(callMe == finalString)
{
try
{
startActivity(new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + finalString)));
}
catch (Exception e)
{
e.printStackTrace();
}
}
else
{
tryProcessAgain.onShutterButtonPressContinuous();
}
}
}

JmDNS Error - The method getInetAddresses() is undefined for the type ServiceInfo

For some reason it doesn't like the getInetAddresses() method in the lines:
Enumeration additions = (Enumeration) ev.getInfo().getInetAddresses();
if (ev.getInfo().getInetAddresses() != null && ev.getInfo().getInetAddresses().length > 0) {
additions = ev.getInfo().getInetAddresses()[0].getHostAddress();
}
import java.io.IOException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import javax.jmdns.JmDNS;
import javax.jmdns.ServiceEvent;
import javax.jmdns.ServiceListener;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import javax.jmdns.ServiceInfo;
private String type = "_workstation._tcp.local.";
private JmDNS jmdns = null;
private ServiceListener listener = null;
private ServiceInfo serviceInfo;
private void setUp() {
android.net.wifi.WifiManager wifi = (android.net.wifi.WifiManager) getSystemService(android.content.Context.WIFI_SERVICE);
lock = wifi.createMulticastLock("mylockthereturn");
lock.setReferenceCounted(true);
lock.acquire();
try {
jmdns = JmDNS.create();
jmdns.addServiceListener(type, listener = new ServiceListener() {
#Override
public void serviceResolved(ServiceEvent ev) {
Enumeration additions = (Enumeration) ev.getInfo().getInetAddresses();
if (ev.getInfo().getInetAddresses() != null && ev.getInfo().getInetAddresses().length > 0) {
additions = ev.getInfo().getInetAddresses()[0].getHostAddress();
}
notifyUser("Service resolved: " + ev.getInfo().getQualifiedName() + " port:" + ev.getInfo().getPort() + additions);
}
#Override
public void serviceRemoved(ServiceEvent ev) {
notifyUser("Service removed: " + ev.getName());
}
#Override
public void serviceAdded(ServiceEvent event) {
// Required to force serviceResolved to be called again (after the first search)
jmdns.requestServiceInfo(event.getType(), event.getName(), 1);
}
});
serviceInfo = ServiceInfo.create("_test._tcp.local.", "AndroidTest", 0, "plain test service from android");
jmdns.registerService(serviceInfo);
} catch (IOException e) {
e.printStackTrace();
return;
}
}
Try download and use latest version of JmDNS from Maven Central Repository, apparently there are some issues related to the jar file downloaded from their SourceForge home page. jar file from SourceForge doesn't play quite nice with Android.
Check out this SO question for more details. Hope this help.

connection to a NFC-tag in an android app

I'm trying to write an android app for may Nexus S that is able to write a simple Text Record on a NFC-Tag. My problem is the connection-establishment to the NFC-Tag.
I've implemented two activities called "TagWriter" & "TagWriterStartPage".
Here ist the "TagWriter"-activity:
package nfc.example.writer;
import java.util.Locale;
import com.google.common.base.Charsets;
import com.google.common.primitives.Bytes;
import android.app.Activity;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class TagWriter extends Activity
{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.tagwriter);
Intent intent = this.getIntent();
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
writeTag(tag);
}
private void writeTag(Tag t)
{
Ndef tag = Ndef.get(t);
Locale locale = Locale.US;
final byte[] langBytes = locale.getLanguage().getBytes(Charsets.US_ASCII);
String text = "Tag, you're it!";
final byte[] textBytes = text.getBytes(Charsets.UTF_8);
final int utfBit = 0;
final char status = (char) (utfBit + langBytes.length);
final byte[] data = Bytes.concat(new byte[] {(byte) status}, langBytes, textBytes);
NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data);
try
{
NdefRecord[] records = {record};
NdefMessage message = new NdefMessage(records);
tag.connect();
boolean connected = tag.isConnected();
boolean writeable = tag.isWritable();
if( connected && writeable)
{
tag.writeNdefMessage(message);
}
tag.close();
}
catch (Exception e)
{
//do error handling
}
}
}
The activity "TagWriter" is called when I put my device on the NFC-tag. Everytime the method "tag.connect()" is called, there occures an exception.
Can anyone help me to solve the problem???
Thanks,
Dennis
this might work better:
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
ndef.connect();
ndef.writeNdefMessage(message);
} else {
NdefFormatable format = NdefFormatable.get(tag);
if (format != null) {
format.connect();
format.format(message);
}
}
need other checks in there for real use (capacity, writable etc) - but that is bare bones..

Categories

Resources