Jump to content

Recommended Posts

Posted

Tenho uma aplicação simples em android que faz download do conteúdo de uma página web e envia para uma impressora portátil bluetooth. Esta aplicação estava a funcionar perfeitamente mas com as alterações da google neste momento não se consegue instalar em android a partir da versão 12. Fiz esta aplicação a partir de um exemplo de um fabricante de impressoras chines já há alguns anos e pouco mais mexi na app. Agora tenho que fazer alterações para colocar isto a funcionar mas estou com algumas dificuldades pois não sou especialista em android.

Já alterei o TargetSdkVersion da app no android studio mas ao tentar fazer download do conteúdo da pagina web "estoura" e dá erro. Pelo que entendi o erro acontece porque a função que faz o download e enviar para bluetooth está na actitvity principal da app e isso agora não é permitido. Esta função é chamada a partir do evento de click num botão.

 

	public void onClick(View v) {

		if (v.getId() == R.id.btn_printdoc) {
			printdoc();
		}
      //...
    }

	public void printdoc(){
		try{
			connectToPrinter();

		}   catch (Exception e) {
			e.printStackTrace();
		}
		try{
			//BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new URL(uriToPrint).openConnection().getInputStream()));
			URL myUrl = new URL(uriToPrint);
			HttpURLConnection myCon = (HttpURLConnection) myUrl.openConnection();
			InputStream stream = null;
			try {
				stream = myCon.getInputStream();
			} catch(Exception ex){
				ex.printStackTrace();
				Toast.makeText(this, ex.getMessage(), Toast.LENGTH_SHORT).show();
			}
			InputStreamReader reader = new InputStreamReader(stream);
			BufferedReader bufferedReader = new BufferedReader(reader);

			byte[] init = {0x1b,0x74,0x03};
			woosim.controlCommand(init, init.length);
			
			//StringBuilder sb = new StringBuilder();
			String line = null;
			while( ( line = bufferedReader.readLine() ) != null) {
				String noHTMLString = ConverCore(line);
				Pattern pattern = Pattern.compile("data=\"(.*?)\"");
				Matcher matcher = pattern.matcher(line);
				if (matcher.find()){
				    woosim.saveSpool(UTF_8, noHTMLString + "\n", 0x11, false);
				    //Toast.makeText(this, Integer.parseInt(matcher.group(1)), Toast.LENGTH_SHORT).show();
				}else{
					pattern = Pattern.compile("data-src=\"(.*?)\"");
					matcher = pattern.matcher(line);
					if(matcher.find()){
						try {
							downloadFile(matcher.group(1), Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + "/sig.bmp");
							int resp = this.PrintImage(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/sig.bmp", 0, 0, 0);
						}catch(Exception ex) {
						}
					}else {
						woosim.saveSpool(UTF_8, noHTMLString + "\n", 0, false);
					}
				}
			}
			
			bufferedReader.close();

			byte[] ff ={0x0c};
			woosim.controlCommand(ff, 1);
			woosim.printSpool(true);

			Toast.makeText(this, "Impressão concluida.", Toast.LENGTH_SHORT).show();
		}  catch (Exception e) {
			e.printStackTrace();
			Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
		}
	}

Agora estou com problemas a fazer o download através da InputStream e desconfio que irá acontecer também no envio vi bluetooth. Mas uma coisa de cada vez...

Já li que poderia ser através de uma asyncTask mas isto parece que também já foi descontinuado. Também li qualquer coisa sobre Executors ou Threads mas ainda não entendi bem como posso fazer isto.

Alguém me sabe dizer como posso fazer isto?

Posted

Disclaimer: Não tenho experiência com Android (e mesmo executores é algo que raramente tenho de configurar manualmente).

Podes criar facilmente um executor com o seguinte código:

private final ExecutorService executorService = Executors.newFixedThreadPool(2);

Isto deverá estar armazenado num campo da classe (e assumo que a classe seja um singleton, caso contrário deves ver como partilhar o executor, com dependency injection ou similar).

Depois podes submeter um Runnable para o executor, que simplesmente corre o teu método actual:

public void printAsync() {
	executor.execute(new Runnable() {
        @Override
        public void run() {
            printdoc();
        }
    });
}

Se tiveres mais problemas, é capaz de ser boa ideia separar o método printdoc em vários métodos para facilitar a implementação de testes unitários.

  • 2 months later...
Posted (edited)

Boas desconfiado,

Isso já deve estourar a mais tempo dado que executar esse codigo na main thread já não é permitido por razões de segurança e nao bloquear a UI isso agora tem de ser feito numa thread ou como falaste um executor ou agora tambem podes usar coroutines se migrares para Kotlin.

Usando uma Thread é tão simples como

new Thread(new Runnable() { printdoc(); }).start();

 

Edited by Estevex

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.